package org.fmi.lje.graphics.bcel;

import java.util.HashMap;
import java.util.Map;

import org.apache.bcel.classfile.AccessFlags;
import org.apache.bcel.classfile.Field;
import org.apache.bcel.classfile.Method;
import org.apache.bcel.generic.Type;

public class BcelUtil {

	private static final Map<Object, String> cache = new HashMap<Object, String>();

	public static String asString(Field field) {
		if (!cache.containsKey(field)) {
			StringBuilder sb = new StringBuilder();

			sb.append(getAccessFlagsChar(field));
			sb.append(field.getName());
			sb.append(" : ");
			sb.append(field.getType());

			cache.put(field, sb.toString());
		}

		return cache.get(field);
	}

	public static String asString(Method method) {
		if (!cache.containsKey(method)) {
			StringBuilder sb = new StringBuilder();

			sb.append(getAccessFlagsChar(method));
			sb.append(method.getName());
			sb.append("(");

			String prefix = "";
			for (Type type : method.getArgumentTypes()) {
				sb.append(prefix);
				prefix = ", ";
				sb.append(type);
			}

			sb.append(")");

			if (method.getReturnType() != Type.VOID) {
				sb.append(" : ");
				sb.append(method.getReturnType());
			}

			if (method.isAbstract()) {
				sb.append(" { abstract }");
			}

			cache.put(method, sb.toString());
		}
		
		return cache.get(method);
	}

	private static String getAccessFlagsChar(AccessFlags flag) {
		StringBuilder sb = new StringBuilder();

		if (flag.isPublic()) {
			sb.append("+");
		}

		if (flag.isPrivate()) {
			sb.append("-");
		}

		if (flag.isProtected()) {
			sb.append("#");
		}
		
		sb.append(" ");

		if (flag.isStatic()) {
			sb.append("static ");
		}

		return sb.toString();
	}
}
